namespace ObjectPersistence {
    using System;
    using System.Text;
    using System.Collections;
    using System.Data.Common;
    using System.Transactions;
    using System.Collections.Generic;
    
    public partial class InformationAssembler : AssemblerBaseUpdatable<KYO.DAL.Information, InformationCriteria, InformationRowMap, InformationDomainObjectFactory> {
        public InformationAssembler() {
            base.connection = new System.Data.SqlClient.SqlConnection(GlobalUtil.Constants.ConnectionString);
        }
        protected override System.Data.Common.DbConnection InstanceConnection {
            get {
                return this.connection;
            }
        }
        /// <summary>Reads a single object from the database corresponding to the object keys which are passed in</summary>
        public KYO.DAL.Information ReadSingleByKey(int InformationID) {
            InformationCriteria criteria = new InformationCriteria();
            criteria.Set_InformationID(InformationCriteria.AVAILABLE_OPERATORS.EQUALS, InformationID);
            return this.ReadSingle(criteria);
        }

        internal override void MakePersistent(KYO.DAL.Information PersistentObject, bool cascade, System.Data.Common.DbCommand comm) {
            if ((PersistentObject.IsNew == false)) {
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) 
                            && (PersistentObject.ChangesMade == false))) {
                    return;
                }
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) == false)) {
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                }
            }

            if ((PersistentObject.IsNew || PersistentObject.ChangesMade)) {
                InformationUpdateFactory updateFactory = new InformationUpdateFactory();
                comm.Parameters.Clear();
                if ((PersistentObject.IsNew == false)) {
                    updateFactory.updateCommandText(PersistentObject, comm);
                    int numRows = comm.ExecuteNonQuery();
                    if ((numRows == 0)) {
                        throw new NoRowsUpdated();
                    }
                }
                else {
                    updateFactory.insertCommandText(PersistentObject, comm);
                    comm.CommandText = (comm.CommandText + "; SELECT SCOPE_IDENTITY();");
                    decimal NewIdentityKey = ((decimal)(comm.ExecuteScalar()));
                    PersistentObject.InformationID = ((int)(NewIdentityKey));
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                    PersistentObject.IsNew = false;
                }
            }
            PersistentObject.ChangesMade = false;
            if (cascade) {
                CommentAssembler tempCommentAssembler = new CommentAssembler();
                CategoryAssembler tempCategoryAssembler = new CategoryAssembler();

                if ((PersistentObject.IsCommentCollectionNull() == false)) {
                    for (int i1 = 0; (i1 < PersistentObject.CommentCollection.Count); i1 = (i1 + 1)) {
                        if (((PersistentObject.CommentCollection[i1].InformationId == PersistentObject.InformationID) 
                                    == false)) {
                            PersistentObject.CommentCollection[i1].InformationId = PersistentObject.InformationID;
                        }
                        comm.Parameters.Clear();
                        tempCommentAssembler.MakePersistent(PersistentObject.CommentCollection[i1], cascade, comm);
                    }
                    PersistentObject.CommentCollection.Clean();
                    for (int i1a = 0; (i1a < PersistentObject.CommentCollection.Deleted.Count); i1a = (i1a + 1)) {
                        tempCommentAssembler.Delete(PersistentObject.CommentCollection.Deleted[i1a]);
                    }
                    PersistentObject.CommentCollection.Synch();
                }
                if ((PersistentObject.IsCategoryCollNull() == false)) {
                    for (int i1 = 0; (i1 < PersistentObject.CategoryColl.Count); i1 = (i1 + 1)) {
                        comm.Parameters.Clear();
                        tempCategoryAssembler.MakePersistent(PersistentObject.CategoryColl[i1], cascade, comm);
                    }
                    PersistentObject.CategoryColl.Clean();
                    this.InsertAddedCategoryCollMappingTable(PersistentObject, comm);
                    this.RemoveDeletedCategoryCollMappingTableEntries(PersistentObject, comm);
                    PersistentObject.CategoryColl.Synch();
                }
                tempCommentAssembler.Dispose();
                tempCategoryAssembler.Dispose();
            }
        }

        internal override void Delete(KYO.DAL.Information PersistentObject, System.Data.Common.DbCommand comm) {
            this.DeleteCategoryCollMappingTable(PersistentObject, comm);

            comm.Parameters.Clear();

            InformationSelectionFactory tempInformationSelectionFactory = new InformationSelectionFactory();
            string sql = "DELETE FROM [dbo].[Information]";
            comm.CommandText = sql;
            tempInformationSelectionFactory.getDefaultSelection(PersistentObject, comm);
            comm.ExecuteNonQuery();
        }

        #region Manage Mapping Tables
        private void InsertAddedCategoryCollMappingTable(KYO.DAL.Information PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "IF NOT EXISTS (SELECT 1 FROM [dbo].[InformationInCategory] (nolock) WHERE [Catego" +
                "ryID] = @rarg0 AND [InformationID] = @larg1) INSERT INTO [dbo].[InformationInCat" +
                "egory] ([CategoryID] , [InformationID] ) VALUES (@rarg0, @larg1)";
            for (int i = 0; (i < PersistentObject.CategoryColl.Added.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@larg1", PersistentObject.InformationID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg0", PersistentObject.CategoryColl.Added[i].CategoryID);
                comm.ExecuteNonQuery();
            }
        }

        private void DeleteCategoryCollMappingTable(KYO.DAL.Information PersistentObject, System.Data.Common.DbCommand comm) {
            comm.Parameters.Clear();
            comm.CommandText = "DELETE FROM [dbo].[InformationInCategory] WHERE [InformationID]=@arg1";
            ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", PersistentObject.InformationID);
            comm.ExecuteNonQuery();
        }

        private void RemoveDeletedCategoryCollMappingTableEntries(KYO.DAL.Information PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "DELETE FROM [dbo].[InformationInCategory] WHERE  [CategoryID]=@rarg0 AND  [Inform" +
                "ationID]=@arg1";
            for (int i = 0; (i < PersistentObject.CategoryColl.Deleted.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", PersistentObject.InformationID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg0", PersistentObject.CategoryColl.Deleted[i].CategoryID);
                comm.ExecuteNonQuery();
            }
        }
        #endregion

        #region Manage Child Objects / Collections
        /// Reads the KYO.DAL.Comment from the database corresponding to the object keys passed as parameters
        // <param name="localInformationID">Corresponds to Information attribute InformationID</param
        public BusinessLayerHelper.PersistentList<KYO.DAL.Comment> GetCommentCollection(int localInformationID) {
            BusinessLayerHelper.PersistentList<KYO.DAL.Comment> result = new BusinessLayerHelper.PersistentList<KYO.DAL.Comment>();
            CommentCriteria CommentCriteriaSingle = new CommentCriteria();
            CommentCriteriaSingle.Set_InformationId(CommentCriteria.AVAILABLE_OPERATORS.EQUALS, localInformationID);
            CommentAssembler _tempAssem = new CommentAssembler();
            result.FillData(_tempAssem.ReadCollection(CommentCriteriaSingle));
            return result;
        }

        /// Reads the KYO.DAL.Category from the database corresponding to the object keys passed as parameters
        // <param name="local">Corresponds to Information attribute </param
        // <param name="localInformationID">Corresponds to Information attribute InformationID</param
        public BusinessLayerHelper.PersistentList<KYO.DAL.Category> GetCategoryColl(int localInformationID) {
            BusinessLayerHelper.PersistentList<KYO.DAL.Category> result = new BusinessLayerHelper.PersistentList<KYO.DAL.Category>();
            System.Data.Common.DbConnection tempConnection = this.InstanceConnection;
            try {
                tempConnection.Open();
                System.Data.Common.DbCommand comm = tempConnection.CreateCommand();
                comm.CommandText = (CategoryAssembler.SELECT + " FROM [dbo].[InformationInCategory] INNER JOIN [dbo].[Category] ON [dbo].[Informa" +
                    "tionInCategory].[CategoryID] = [dbo].[Category].[CategoryID] WHERE [dbo].[Inform" +
                    "ationInCategory].[InformationID] = @arg1");
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", localInformationID);
                CategoryAssembler _tempAssem = new CategoryAssembler();
                result.FillData(_tempAssem.ReadCollectionCustom(comm));
            }
            finally {
                tempConnection.Close();
            }
            return result;
        }
        #endregion

        #region Helper Utilities
        protected override InformationRowMap fillRowMap(System.Data.Common.DbDataReader reader) {
            InformationRowMap result = new InformationRowMap();
            result.InformationID = reader.GetInt32(reader.GetOrdinal("dboInformationDOTInformationID"));
            result.Title = reader.GetString(reader.GetOrdinal("dboInformationDOTTitle"));
            result.Abstract = reader.GetString(reader.GetOrdinal("dboInformationDOTAbstract"));
            result.Content = reader.GetString(reader.GetOrdinal("dboInformationDOTContent"));
            result.Odering = reader.GetInt32(reader.GetOrdinal("dboInformationDOTOdering"));
            result.Published = reader.GetBoolean(reader.GetOrdinal("dboInformationDOTPublished"));
            result.DateCreate = reader.GetDateTime(reader.GetOrdinal("dboInformationDOTDateCreate"));
            result.AllowComment = reader.GetBoolean(reader.GetOrdinal("dboInformationDOTAllowComment"));
            result.ImageUrl = reader.GetString(reader.GetOrdinal("dboInformationDOTImageUrl"));
            return result;
        }
        internal override void ClearList() {
            GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Clear();
        }

        public override string Abstract_SELECT {
            get {
                return ("SELECT " + InformationAssembler.RawFields);
            }
        }
        protected override string InstanceTable {
            get {
                return "[dbo].[Information]";
            }
        }
        public const string RawFields = @"[dbo].[Information].[InformationID] AS dboInformationDOTInformationID, [dbo].[Information].[Abstract] AS dboInformationDOTAbstract, [dbo].[Information].[AllowComment] AS dboInformationDOTAllowComment, [dbo].[Information].[Content] AS dboInformationDOTContent, [dbo].[Information].[DateCreate] AS dboInformationDOTDateCreate, [dbo].[Information].[ImageUrl] AS dboInformationDOTImageUrl, [dbo].[Information].[Odering] AS dboInformationDOTOdering, [dbo].[Information].[Published] AS dboInformationDOTPublished, [dbo].[Information].[Title] AS dboInformationDOTTitle";
        public const string SELECT = @"SELECT [dbo].[Information].[InformationID] AS dboInformationDOTInformationID, [dbo].[Information].[Abstract] AS dboInformationDOTAbstract, [dbo].[Information].[AllowComment] AS dboInformationDOTAllowComment, [dbo].[Information].[Content] AS dboInformationDOTContent, [dbo].[Information].[DateCreate] AS dboInformationDOTDateCreate, [dbo].[Information].[ImageUrl] AS dboInformationDOTImageUrl, [dbo].[Information].[Odering] AS dboInformationDOTOdering, [dbo].[Information].[Published] AS dboInformationDOTPublished, [dbo].[Information].[Title] AS dboInformationDOTTitle";
        #endregion
    }
}
